import { io, Socket } from 'socket.io-client'
import { AuthUtils } from './auth'

// WebSocket连接管理器
class WebSocketManager {
  private socket: Socket | null = null
  private isConnected = false
  private reconnectAttempts = 0
  private maxReconnectAttempts = 5
  private reconnectDelay = 1000
  private currentConversationId: string | null = null
  
  // 事件监听器
  private messageListeners: Array<(message: any) => void> = []
  private connectionListeners: Array<(connected: boolean) => void> = []
  private errorListeners: Array<(error: any) => void> = []

  constructor() {
    this.connect()
  }

  // 连接WebSocket
  private connect() {
    const token = AuthUtils.getToken()
    if (!token) {
      console.error('WebSocket连接失败：缺少认证token')
      return
    }

    try {
      this.socket = io('ws://localhost:3000', {
        auth: {
          token: token
        },
        transports: ['websocket'],
        autoConnect: true,
        reconnection: true,
        reconnectionAttempts: this.maxReconnectAttempts,
        reconnectionDelay: this.reconnectDelay
      })

      this.setupEventListeners()
    } catch (error) {
      console.error('WebSocket连接创建失败:', error)
      this.notifyError(error)
    }
  }

  // 设置事件监听器
  private setupEventListeners() {
    if (!this.socket) return

    // 连接成功
    this.socket.on('connect', () => {
      console.log('WebSocket连接成功')
      this.isConnected = true
      this.reconnectAttempts = 0
      this.notifyConnection(true)
    })

    // 连接断开
    this.socket.on('disconnect', (reason) => {
      console.log('WebSocket连接断开:', reason)
      this.isConnected = false
      this.notifyConnection(false)
    })

    // 连接错误
    this.socket.on('connect_error', (error) => {
      console.error('WebSocket连接错误:', error)
      this.reconnectAttempts++
      
      if (this.reconnectAttempts >= this.maxReconnectAttempts) {
        console.error('WebSocket重连次数超限，停止重连')
        this.notifyError(new Error('连接失败，请检查网络或重新登录'))
      }
    })

    // 认证错误
    this.socket.on('error', (error) => {
      console.error('WebSocket认证错误:', error)
      this.notifyError(new Error(error.message || '认证失败'))
    })

    // 成功加入会话
    this.socket.on('joined_conversation', (data) => {
      console.log('成功加入会话:', data)
    })

    // 接收新消息
    this.socket.on('new_message', (message) => {
      console.log('收到新消息:', message)
      this.notifyMessage(message)
    })

    // 成功离开会话
    this.socket.on('left_conversation', (data) => {
      console.log('成功离开会话:', data)
    })
  }

  // 加入会话
  public joinConversation(conversationId: string): Promise<void> {
    return new Promise((resolve, reject) => {
      if (!this.socket || !this.isConnected) {
        reject(new Error('WebSocket未连接'))
        return
      }

      // 如果已经在当前会话中，直接返回
      if (this.currentConversationId === conversationId) {
        resolve()
        return
      }

      // 先离开当前会话（如果有）
      if (this.currentConversationId) {
        this.leaveConversation(this.currentConversationId)
      }

      // 加入新会话
      this.socket.emit('join_conversation', { conversationId: parseInt(conversationId) })
      this.currentConversationId = conversationId
      
      // 监听加入成功事件
      const onJoined = (data: any) => {
        if (data.conversationId.toString() === conversationId) {
          this.socket?.off('joined_conversation', onJoined)
          resolve()
        }
      }
      
      const onError = (error: any) => {
        this.socket?.off('error', onError)
        reject(new Error(error.message || '加入会话失败'))
      }

      this.socket.on('joined_conversation', onJoined)
      this.socket.on('error', onError)

      // 设置超时
      setTimeout(() => {
        this.socket?.off('joined_conversation', onJoined)
        this.socket?.off('error', onError)
        reject(new Error('加入会话超时'))
      }, 5000)
    })
  }

  // 离开会话
  public leaveConversation(conversationId: string): void {
    if (!this.socket || !this.isConnected) {
      console.warn('WebSocket未连接，无法离开会话')
      return
    }

    this.socket.emit('leave_conversation', { conversationId: parseInt(conversationId) })
    
    if (this.currentConversationId === conversationId) {
      this.currentConversationId = null
    }
  }

  // 发送消息
  public sendMessage(conversationId: string, content: string): Promise<void> {
    return new Promise((resolve, reject) => {
      if (!this.socket || !this.isConnected) {
        reject(new Error('WebSocket未连接'))
        return
      }

      if (!content.trim()) {
        reject(new Error('消息内容不能为空'))
        return
      }

      if (content.length > 1000) {
        reject(new Error('消息长度不能超过1000个字符'))
        return
      }

      this.socket.emit('send_message', {
        conversationId: parseInt(conversationId),
        content: content.trim()
      })

      // Socket.IO的消息发送是异步的，这里直接resolve
      // 实际的消息确认会通过new_message事件返回
      resolve()
    })
  }

  // 添加消息监听器
  public onMessage(callback: (message: any) => void): () => void {
    this.messageListeners.push(callback)
    return () => {
      const index = this.messageListeners.indexOf(callback)
      if (index > -1) {
        this.messageListeners.splice(index, 1)
      }
    }
  }

  // 添加连接状态监听器
  public onConnection(callback: (connected: boolean) => void): () => void {
    this.connectionListeners.push(callback)
    return () => {
      const index = this.connectionListeners.indexOf(callback)
      if (index > -1) {
        this.connectionListeners.splice(index, 1)
      }
    }
  }

  // 添加错误监听器
  public onError(callback: (error: any) => void): () => void {
    this.errorListeners.push(callback)
    return () => {
      const index = this.errorListeners.indexOf(callback)
      if (index > -1) {
        this.errorListeners.splice(index, 1)
      }
    }
  }

  // 通知消息监听器
  private notifyMessage(message: any) {
    this.messageListeners.forEach(callback => {
      try {
        callback(message)
      } catch (error) {
        console.error('消息监听器执行错误:', error)
      }
    })
  }

  // 通知连接状态监听器
  private notifyConnection(connected: boolean) {
    this.connectionListeners.forEach(callback => {
      try {
        callback(connected)
      } catch (error) {
        console.error('连接状态监听器执行错误:', error)
      }
    })
  }

  // 通知错误监听器
  private notifyError(error: any) {
    this.errorListeners.forEach(callback => {
      try {
        callback(error)
      } catch (error) {
        console.error('错误监听器执行错误:', error)
      }
    })
  }

  // 获取连接状态
  public getConnectionStatus(): boolean {
    return this.isConnected
  }

  // 获取当前会话ID
  public getCurrentConversationId(): string | null {
    return this.currentConversationId
  }

  // 断开连接
  public disconnect(): void {
    if (this.socket) {
      this.socket.disconnect()
      this.socket = null
    }
    this.isConnected = false
    this.currentConversationId = null
    this.reconnectAttempts = 0
  }

  // 重新连接
  public reconnect(): void {
    this.disconnect()
    this.connect()
  }
}

// 创建全局WebSocket管理器实例
export const websocketManager = new WebSocketManager()

// 导出类型
export type { Socket } from 'socket.io-client'
export { WebSocketManager }